import os
from datetime import datetime
import ifcopenshell
import ifcopenshell.geom
import uuid


def create_ifc_model(mesh, alpha, C, volume, area):
    """创建IFC模型"""
    try:
        print("\n开始创建IFC模型...")
        # 创建新的IFC文件
        model = ifcopenshell.file()

        # 创建项目
        project = model.create_entity("IfcProject",
                                      GlobalId=ifcopenshell.guid.new(),
                                      Name="路堤边坡模型",
                                      Description=f"坡脚角度: {alpha}°, 底座长度: {C}m"
                                      )

        # 创建单位信息
        print("   设置单位信息...")
        length_unit = model.create_entity("IfcSIUnit",
                                          UnitType="LENGTHUNIT",
                                          Name="METRE"
                                          )
        units = model.create_entity("IfcUnitAssignment", Units=[length_unit])
        project.UnitsInContext = units

        # 创建几何上下文
        context = model.create_entity("IfcGeometricRepresentationContext",
                                      ContextType="Model",
                                      CoordinateSpaceDimension=3,
                                      Precision=1.0e-5
                                      )
        project.RepresentationContexts = [context]

        # 创建场地（向上继承）
        print("   创建场地...")
        site = model.create_entity("IfcSite",
                                   GlobalId=ifcopenshell.guid.new(),
                                   Name="路堤边坡场地",
                                   Description=f"填筑体积: {volume:.2f}m³, 征地面积: {area:.2f}m²",
                                   CompositionType="ELEMENT",
                                   ObjectPlacement=model.create_entity("IfcLocalPlacement"),
                                   )

        # 创建建筑（向上继承）
        print("   创建建筑...")
        building = model.create_entity("IfcBuilding",
                                       GlobalId=ifcopenshell.guid.new(),
                                       Name="路堤边坡",
                                       Description=f"坡脚角度: {alpha}°",
                                       CompositionType="ELEMENT",
                                       ObjectPlacement=model.create_entity("IfcLocalPlacement",
                                                                           PlacementRelTo=site.ObjectPlacement),
                                       )

        # 创建楼层（向上继承）
        print("   创建楼层...")
        storey = model.create_entity("IfcBuildingStorey",
                                     GlobalId=ifcopenshell.guid.new(),
                                     Name="基础层",
                                     Description="路堤边坡基础层",
                                     CompositionType="ELEMENT",
                                     ObjectPlacement=model.create_entity("IfcLocalPlacement",
                                                                         PlacementRelTo=building.ObjectPlacement),
                                     )

        # 创建关系
        model.create_entity("IfcRelAggregates",
                            GlobalId=ifcopenshell.guid.new(),
                            RelatingObject=project,
                            RelatedObjects=[site]
                            )

        model.create_entity("IfcRelAggregates",
                            GlobalId=ifcopenshell.guid.new(),
                            RelatingObject=site,
                            RelatedObjects=[building]
                            )

        model.create_entity("IfcRelAggregates",
                            GlobalId=ifcopenshell.guid.new(),
                            RelatingObject=building,
                            RelatedObjects=[storey]
                            )

        # 创建几何表示
        print("   创建几何表示...")
        # 转换网格为IFC格式，确保坐标是浮点数列表
        vertices = [[float(coord) for coord in v] for v in mesh.vertices]
        faces = [list(f) for f in mesh.faces]

        # 创建点和面，使用列表而不是元组
        points = [model.create_entity("IfcCartesianPoint", Coordinates=list(v)) for v in vertices]

        # 创建面片
        face_entities = []
        for face in faces:
            face_points = [points[i] for i in face]
            polyloop = model.create_entity("IfcPolyLoop", Polygon=face_points)
            face_surface = model.create_entity("IfcFaceSurface",
                                               FaceSurface=model.create_entity("IfcPlane", Position=model.create_entity(
                                                   "IfcAxis2Placement3D",
                                                   Location=model.create_entity("IfcCartesianPoint",
                                                                                Coordinates=(0., 0., 0.)))),
                                               SameSense=True)
            face_entities.append(model.create_entity("IfcFace", Bounds=[
                model.create_entity("IfcFaceOuterBound", Bound=polyloop, Orientation=True)
            ]))

        # 创建几何形状
        shape = model.create_entity("IfcFacetedBrep",
                                    Outer=model.create_entity("IfcClosedShell", CfsFaces=face_entities))

        # 创建形状表示
        shape_rep = model.create_entity("IfcShapeRepresentation",
                                        ContextOfItems=context,
                                        RepresentationType="Brep",
                                        Items=[shape]
                                        )

        # 创建产品定义形状
        product_def = model.create_entity("IfcProductDefinitionShape",
                                          Representations=[shape_rep]
                                          )

        # 创建路堤构件
        print("   创建路堤构件...")
        embankment = model.create_entity("IfcBuildingElementProxy",
                                         GlobalId=ifcopenshell.guid.new(),
                                         Name="路堤边坡构件",
                                         Description=f"填筑体积: {volume:.2f}m³",
                                         ObjectType="路堤",
                                         ObjectPlacement=model.create_entity("IfcLocalPlacement",
                                                                             PlacementRelTo=storey.ObjectPlacement),
                                         Representation=product_def
                                         )

        # 创建构件与楼层的关系
        model.create_entity("IfcRelContainedInSpatialStructure",
                            GlobalId=ifcopenshell.guid.new(),
                            RelatingStructure=storey,
                            RelatedElements=[embankment]
                            )

        # 保存IFC文件
        try:
            # 创建专门的 IFC 文件夹
            ifc_dir = os.path.join(os.getcwd(), "output_models", "ifc_files")
            os.makedirs(ifc_dir, exist_ok=True)
            print(f"\n创建IFC文件夹: {ifc_dir}")

            # 生成带时间戳的文件名，移除 H1 参数
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            ifc_filename = f"Embankment_A{alpha:.1f}_C{C:.1f}_{timestamp}.ifc"
            ifc_path = os.path.join(ifc_dir, ifc_filename)

            print(f"准备保存IFC文件: {ifc_path}")
            model.write(ifc_path)
            print("IFC文件写入完成")

            # 验证文件是否成功保存
            if os.path.exists(ifc_path):
                print(f"文件已成功保存: {ifc_path}")
                print(f"文件大小: {os.path.getsize(ifc_path) / 1024:.1f} KB")
                # 尝试打开文件夹
                try:
                    os.startfile(ifc_dir)
                    print("已自动打开IFC文件夹")
                except:
                    print(f"请手动打开目录查看文件: {ifc_dir}")
                return ifc_path
            else:
                print(f"警告：文件未能成功保存: {ifc_path}")
                # 检查目录权限
                try:
                    with open(ifc_path, 'w') as f:
                        f.write("test")
                    os.remove(ifc_path)
                    print("目录写入权限正常")
                except Exception as e:
                    print(f"目录写入权限问题: {str(e)}")
                return None

        except Exception as e:
            print(f"保存IFC文件时发生错误: {str(e)}")
            import traceback
            traceback.print_exc()
            return None

    except Exception as e:
        print(f"创建IFC模型时发生错误: {str(e)}")
        import traceback
        traceback.print_exc()
        return None